// [z-paging]下拉刷新view模块
import u from '.././z-paging-utils';
import c from '.././z-paging-constant';
import Enum from '.././z-paging-enum';

export default {
  props: {
    //下拉刷新的主题样式，支持black，white，默认black
    refresherThemeStyle: {
      type: String,
      default: u.gc('refresherThemeStyle', ''),
    },
    //自定义下拉刷新中左侧图标的样式
    refresherImgStyle: {
      type: Object,
      default: function () {
        return u.gc('refresherImgStyle', {});
      },
    },
    //自定义下拉刷新中右侧状态描述文字的样式
    refresherTitleStyle: {
      type: Object,
      default: function () {
        return u.gc('refresherTitleStyle', {});
      },
    },
    //自定义下拉刷新中右侧最后更新时间文字的样式(show-refresher-update-time为true时有效)
    refresherUpdateTimeStyle: {
      type: Object,
      default: function () {
        return u.gc('refresherUpdateTimeStyle', {});
      },
    },
    //在微信小程序和QQ小程序中，是否实时监听下拉刷新中进度，默认为否
    watchRefresherTouchmove: {
      type: Boolean,
      default: u.gc('watchRefresherTouchmove', false),
    },
    //底部加载更多的主题样式，支持black，white，默认black
    loadingMoreThemeStyle: {
      type: String,
      default: u.gc('loadingMoreThemeStyle', ''),
    },
    //是否只使用下拉刷新，设置为true后将关闭mounted自动请求数据、关闭滚动到底部加载更多，强制隐藏空数据图。默认为否
    refresherOnly: {
      type: Boolean,
      default: u.gc('refresherOnly', false),
    },
    //自定义下拉刷新默认状态下回弹动画时间，单位为毫秒，默认为100毫秒，nvue无效
    refresherDefaultDuration: {
      type: [Number, String],
      default: u.gc('refresherDefaultDuration', 100),
    },
    //自定义下拉刷新结束以后延迟回弹的时间，单位为毫秒，默认为0
    refresherCompleteDelay: {
      type: [Number, String],
      default: u.gc('refresherCompleteDelay', 0),
    },
    //自定义下拉刷新结束回弹动画时间，单位为毫秒，默认为300毫秒(refresherEndBounceEnabled为false时，refresherCompleteDuration为设定值的1/3)，nvue无效
    refresherCompleteDuration: {
      type: [Number, String],
      default: u.gc('refresherCompleteDuration', 300),
    },
    //自定义下拉刷新结束状态下是否允许列表滚动，默认为否
    refresherCompleteScrollable: {
      type: Boolean,
      default: u.gc('refresherCompleteScrollable', false),
    },
    //是否使用自定义的下拉刷新，默认为是，即使用z-paging的下拉刷新。设置为false即代表使用uni scroll-view自带的下拉刷新，h5、App、微信小程序以外的平台不支持uni scroll-view自带的下拉刷新
    useCustomRefresher: {
      type: Boolean,
      default: u.gc('useCustomRefresher', true),
    },
    //自定义下拉刷新下拉帧率，默认为40，过高可能会出现抖动问题
    refresherFps: {
      type: [Number, String],
      default: u.gc('refresherFps', 40),
    },
    //自定义下拉刷新允许触发的最大下拉角度，默认为40度，当下拉角度小于设定值时，自定义下拉刷新动画不会被触发
    refresherMaxAngle: {
      type: [Number, String],
      default: u.gc('refresherMaxAngle', 40),
    },
    //自定义下拉刷新的角度由未达到最大角度变到达到最大角度时，是否继续下拉刷新手势，默认为否
    refresherAngleEnableChangeContinued: {
      type: Boolean,
      default: u.gc('refresherAngleEnableChangeContinued', false),
    },
    //自定义下拉刷新默认状态下的文字
    refresherDefaultText: {
      type: [String, Object],
      default: u.gc('refresherDefaultText', null),
    },
    //自定义下拉刷新松手立即刷新状态下的文字
    refresherPullingText: {
      type: [String, Object],
      default: u.gc('refresherPullingText', null),
    },
    //自定义下拉刷新刷新中状态下的文字
    refresherRefreshingText: {
      type: [String, Object],
      default: u.gc('refresherRefreshingText', null),
    },
    //自定义下拉刷新刷新结束状态下的文字
    refresherCompleteText: {
      type: [String, Object],
      default: u.gc('refresherCompleteText', null),
    },
    //自定义下拉刷新默认状态下的图片
    refresherDefaultImg: {
      type: String,
      default: u.gc('refresherDefaultImg', null),
    },
    //自定义下拉刷新松手立即刷新状态下的图片，默认与refresherDefaultImg一致
    refresherPullingImg: {
      type: String,
      default: u.gc('refresherPullingImg', null),
    },
    //自定义下拉刷新刷新中状态下的图片
    refresherRefreshingImg: {
      type: String,
      default: u.gc('refresherRefreshingImg', null),
    },
    //自定义下拉刷新刷新结束状态下的图片
    refresherCompleteImg: {
      type: String,
      default: u.gc('refresherCompleteImg', null),
    },
    //是否开启自定义下拉刷新刷新结束回弹效果，默认为是
    refresherEndBounceEnabled: {
      type: Boolean,
      default: u.gc('refresherEndBounceEnabled', true),
    },
    //是否开启自定义下拉刷新，默认为是
    refresherEnabled: {
      type: Boolean,
      default: u.gc('refresherEnabled', true),
    },
    //设置自定义下拉刷新阈值，默认为80rpx
    refresherThreshold: {
      type: [Number, String],
      default: u.gc('refresherThreshold', '80rpx'),
    },
    //设置系统下拉刷新默认样式，支持设置 black，white，none，none 表示不使用默认样式，默认为black
    refresherDefaultStyle: {
      type: String,
      default: u.gc('refresherDefaultStyle', 'black'),
    },
    //设置自定义下拉刷新区域背景
    refresherBackground: {
      type: String,
      default: u.gc('refresherBackground', 'transparent'),
    },
    //设置固定的自定义下拉刷新区域背景
    refresherFixedBackground: {
      type: String,
      default: u.gc('refresherFixedBackground', 'transparent'),
    },
    //设置固定的自定义下拉刷新区域高度，默认为0
    refresherFixedBacHeight: {
      type: [Number, String],
      default: u.gc('refresherFixedBacHeight', 0),
    },
    //设置自定义下拉刷新下拉超出阈值后继续下拉位移衰减的比例，范围0-1，值越大代表衰减越多。默认为0.65(nvue无效)
    refresherOutRate: {
      type: Number,
      default: u.gc('refresherOutRate', 0.65),
    },
    //设置自定义下拉刷新下拉时实际下拉位移与用户下拉距离的比值，默认为0.75，即代表若用户下拉10px，则实际位移为7.5px(nvue无效)
    refresherPullRate: {
      type: Number,
      default: u.gc('refresherPullRate', 0.75),
    },
    //是否显示最后更新时间，默认为否
    showRefresherUpdateTime: {
      type: Boolean,
      default: u.gc('showRefresherUpdateTime', false),
    },
    //如果需要区别不同页面的最后更新时间，请为不同页面的z-paging的`refresher-update-time-key`设置不同的字符串
    refresherUpdateTimeKey: {
      type: String,
      default: u.gc('refresherUpdateTimeKey', 'default'),
    },
    //下拉刷新时下拉到“松手立即刷新”状态时是否使手机短振动，默认为否（h5无效）
    refresherVibrate: {
      type: Boolean,
      default: u.gc('refresherVibrate', false),
    },
  },
  data() {
    return {
      R: Enum.Refresher,
      //下拉刷新状态
      refresherStatus: Enum.Refresher.Default,
      refresherTouchstartY: 0,
      lastRefresherTouchmove: null,
      refresherReachMaxAngle: true,
      refresherTransform: 'translateY(0px)',
      refresherTransition: '',
      finalRefresherDefaultStyle: 'black',
      refresherRevealStackCount: 0,
      refresherCompleteTimeout: null,
      refresherCompleteSubTimeout: null,
      refresherEndTimeout: null,
      isTouchmovingTimeout: null,
      refresherTriggered: false,
      isTouchmoving: false,
      isTouchEnded: false,
      isUserPullDown: false,
      privateRefresherEnabled: -1,
      privateShowRefresherWhenReload: false,
      customRefresherHeight: -1,
      showCustomRefresher: false,
      doRefreshAnimateAfter: false,
      isRefresherInComplete: false,
      pullDownTimeStamp: 0,
      moveDis: 0,
      oldMoveDis: 0,
      currentDis: 0,
      oldCurrentMoveDis: 0,
      oldRefresherTouchmoveY: 0,
      oldTouchDirection: '',
    };
  },
  watch: {
    refresherDefaultStyle: {
      handler(newVal) {
        if (newVal.length) {
          this.finalRefresherDefaultStyle = newVal;
        }
      },
      immediate: true,
    },
    refresherStatus(newVal) {
      newVal === Enum.Refresher.Loading && this._cleanRefresherEndTimeout();
      this.refresherVibrate && newVal === Enum.Refresher.ReleaseToRefresh && this._doVibrateShort();
      this.$emit('refresherStatusChange', newVal);
      this.$emit('update:refresherStatus', newVal);
    },
  },
  computed: {
    pullDownDisTimeStamp() {
      return 1000 / this.refresherFps;
    },
    finalRefresherEnabled() {
      if (this.useChatRecordMode) return false;
      if (this.privateRefresherEnabled === -1) return this.refresherEnabled;
      return this.privateRefresherEnabled === 1;
    },
    finalRefresherThreshold() {
      let refresherThreshold = this.refresherThreshold;
      let idDefault = false;
      if (refresherThreshold === '80rpx') {
        idDefault = true;
        if (this.showRefresherUpdateTime) {
          refresherThreshold = '120rpx';
        }
      }
      if (idDefault && this.customRefresherHeight > 0) return this.customRefresherHeight;
      return u.convertTextToPx(refresherThreshold);
    },
    finalRefresherFixedBacHeight() {
      return u.convertTextToPx(this.refresherFixedBacHeight);
    },
    finalRefresherThemeStyle() {
      return this.refresherThemeStyle.length ? this.refresherThemeStyle : this.defaultThemeStyle;
    },
    finalRefresherOutRate() {
      let rate = this.refresherOutRate;
      rate = Math.max(0, rate);
      rate = Math.min(1, rate);
      return rate;
    },
    finalRefresherPullRate() {
      let rate = this.refresherPullRate;
      rate = Math.max(0, rate);
      return rate;
    },
    finalRefresherTransform() {
      if (this.refresherTransform === 'translateY(0px)') return 'none';
      return this.refresherTransform;
    },
    finalShowRefresherWhenReload() {
      return this.showRefresherWhenReload || this.privateShowRefresherWhenReload;
    },
    finalRefresherTriggered() {
      if (!(this.finalRefresherEnabled && !this.useCustomRefresher)) return false;
      return this.refresherTriggered;
    },
    showRefresher() {
      const showRefresher = this.finalRefresherEnabled && this.useCustomRefresher;
      // #ifndef APP-NVUE
      if (this.customRefresherHeight === -1 && showRefresher) {
        setTimeout(() => {
          this.$nextTick(() => {
            this._updateCustomRefresherHeight();
          });
        }, 100);
      }
      // #endif
      return showRefresher;
    },
    hasTouchmove() {
      // #ifdef VUE2
      // #ifdef APP-VUE || H5
      if (this.$listeners && !this.$listeners.refresherTouchmove) return false;
      // #endif
      // #ifdef MP-WEIXIN || MP-QQ
      return this.watchRefresherTouchmove;
      // #endif
      return true;
      // #endif
      return this.watchRefresherTouchmove;
    },
  },
  methods: {
    //终止下拉刷新状态
    endRefresh() {
      this.totalData = this.realTotalData;
      this._refresherEnd();
      this._endSystemLoadingAndRefresh();
    },
    handleRefresherStatusChanged(func) {
      this.refresherStatusChangedFunc = func;
    },
    //自定义下拉刷新被触发
    _onRefresh(fromScrollView = false, isUserPullDown = true) {
      if (fromScrollView && !(this.finalRefresherEnabled && !this.useCustomRefresher)) return;
      this.$emit('onRefresh');
      this.$emit('Refresh');
      // #ifdef APP-NVUE
      if (this.loading) {
        setTimeout(() => {
          this._nRefresherEnd();
        }, 500);
        return;
      }
      // #endif
      if (this.loading || this.isRefresherInComplete) return;
      this.loadingType = Enum.LoadingType.Refresher;
      if (this.nShowRefresherReveal) return;
      this.isUserPullDown = isUserPullDown;
      this.isUserReload = !isUserPullDown;
      this._startLoading(true);
      this.refresherTriggered = true;
      if (this.reloadWhenRefresh && isUserPullDown) {
        this.useChatRecordMode ? this._onLoadingMore('click') : this._reload(false, false, isUserPullDown);
      }
    },
    //自定义下拉刷新被复位
    _onRestore() {
      this.refresherTriggered = 'restore';
      this.$emit('onRestore');
      this.$emit('Restore');
    },
    // #ifndef APP-VUE || MP-WEIXIN || MP-QQ || H5
    //拖拽开始
    _refresherTouchstart(e) {
      this._handleListTouchstart();
      if (this._touchDisabled()) return;
      const touch = u.getTouch(e);
      this._handleRefresherTouchstart(touch);
    },
    // #endif
    //进一步处理拖拽开始结果
    _handleRefresherTouchstart(touch) {
      if (!this.loading && this.isTouchEnded) {
        this.isTouchmoving = false;
      }
      this.loadingType = Enum.LoadingType.Refresher;
      this.isTouchmovingTimeout && clearTimeout(this.isTouchmovingTimeout);
      this.isTouchEnded = false;
      this.refresherTransition = '';
      this.refresherTouchstartY = touch.touchY;
      this.$emit('refresherTouchstart', this.refresherTouchstartY);
      this.lastRefresherTouchmove = touch;
      this._cleanRefresherCompleteTimeout();
      this._cleanRefresherEndTimeout();
    },
    // #ifndef APP-VUE || MP-WEIXIN || MP-QQ || H5
    //拖拽中
    _refresherTouchmove(e) {
      const currentTimeStamp = u.getTime();
      let touch = null;
      let refresherTouchmoveY = 0;
      if (this.watchTouchDirectionChange) {
        touch = u.getTouch(e);
        refresherTouchmoveY = touch.touchY;
        const direction = refresherTouchmoveY > this.oldRefresherTouchmoveY ? 'top' : 'bottom';
        direction === this.oldTouchDirection && this._handleTouchDirectionChange({ direction });
        this.oldTouchDirection = direction;
        this.oldRefresherTouchmoveY = refresherTouchmoveY;
      }
      if (this.pullDownTimeStamp && currentTimeStamp - this.pullDownTimeStamp <= this.pullDownDisTimeStamp) return;
      if (this._touchDisabled()) return;
      this.pullDownTimeStamp = Number(currentTimeStamp);
      touch = u.getTouch(e);
      refresherTouchmoveY = touch.touchY;
      let moveDis = refresherTouchmoveY - this.refresherTouchstartY;
      if (moveDis < 0) return;
      if (this.refresherMaxAngle >= 0 && this.refresherMaxAngle <= 90 && this.lastRefresherTouchmove && this.lastRefresherTouchmove.touchY <= refresherTouchmoveY) {
        if (!moveDis && !this.refresherAngleEnableChangeContinued && this.moveDis < 1 && !this.refresherReachMaxAngle) return;
        const x = Math.abs(touch.touchX - this.lastRefresherTouchmove.touchX);
        const y = Math.abs(refresherTouchmoveY - this.lastRefresherTouchmove.touchY);
        const z = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
        if ((x || y) && x > 1) {
          const angle = (Math.asin(y / z) / Math.PI) * 180;
          if (angle < this.refresherMaxAngle) {
            this.lastRefresherTouchmove = touch;
            this.refresherReachMaxAngle = false;
            return;
          }
        }
      }
      moveDis = this._getFinalRefresherMoveDis(moveDis);
      this._handleRefresherTouchmove(moveDis, touch);
      if (!this.disabledBounce) {
        if (this.isIos) {
          // #ifndef MP-LARK
          this._handleScrollViewDisableBounce({ bounce: false });
          // #endif
        }
        this.disabledBounce = true;
      }
      this._emitTouchmove({ pullingDistance: moveDis, dy: this.moveDis - this.oldMoveDis });
    },
    // #endif
    //进一步处理拖拽中结果
    _handleRefresherTouchmove(moveDis, touch) {
      this.refresherReachMaxAngle = true;
      this.isTouchmovingTimeout && clearTimeout(this.isTouchmovingTimeout);
      this.isTouchmoving = true;
      this.isTouchEnded = false;
      this.refresherStatus = moveDis >= this.finalRefresherThreshold ? Enum.Refresher.ReleaseToRefresh : (this.refresherStatus = Enum.Refresher.Default);
      // #ifndef APP-VUE || MP-WEIXIN || MP-QQ  || H5
      // this.scrollEnable = false;
      this.refresherTransform = `translateY(${moveDis}px)`;
      this.lastRefresherTouchmove = touch;
      // #endif
      this.moveDis = moveDis;
    },
    // #ifndef APP-VUE || MP-WEIXIN || MP-QQ || H5
    //拖拽结束
    _refresherTouchend(e) {
      if (this._touchDisabled() || !this.isTouchmoving) return;
      const touch = u.getTouch(e);
      let refresherTouchendY = touch.touchY;
      let moveDis = refresherTouchendY - this.refresherTouchstartY;
      moveDis = this._getFinalRefresherMoveDis(moveDis);
      this._handleRefresherTouchend(moveDis);
      this._handleScrollViewDisableBounce({ bounce: true });
      this.disabledBounce = false;
    },
    // #endif
    //进一步处理拖拽结束结果
    _handleRefresherTouchend(moveDis) {
      // #ifndef APP-PLUS || H5 || MP-WEIXIN
      if (!this.isTouchmoving) return;
      // #endif
      this.isTouchmovingTimeout && clearTimeout(this.isTouchmovingTimeout);
      this.refresherReachMaxAngle = true;
      this.isTouchEnded = true;
      if (moveDis >= this.finalRefresherThreshold && this.refresherStatus === Enum.Refresher.ReleaseToRefresh) {
        // #ifndef APP-VUE || MP-WEIXIN || MP-QQ || H5
        this.refresherTransform = `translateY(${this.finalRefresherThreshold}px)`;
        this.refresherTransition = 'transform .1s linear';
        // #endif
        this.moveDis = this.finalRefresherThreshold;
        this.refresherStatus = Enum.Refresher.Loading;
        this._doRefresherLoad();
      } else {
        this._refresherEnd();
        this.isTouchmovingTimeout = setTimeout(() => {
          this.isTouchmoving = false;
        }, this.refresherDefaultDuration);
      }
      this.scrollEnable = true;
      this.$emit('refresherTouchend', moveDis);
    },
    //处理列表触摸开始事件
    _handleListTouchstart() {
      if (this.useChatRecordMode && this.autoHideKeyboardWhenChat) {
        uni.hideKeyboard();
        this.$emit('hidedKeyboard');
      }
    },
    //处理scroll-view bounce是否生效
    _handleScrollViewDisableBounce({ bounce }) {
      if (!this.usePageScroll && !this.scrollToTopBounceEnabled) {
        // #ifdef APP-VUE || MP-WEIXIN || MP-QQ || H5
        this.refresherTransition = '';
        // #endif
        this.scrollEnable = bounce;
      }
    },
    //wxs正在下拉状态改变处理
    _handleWxsPullingDownStatusChange(onPullingDown) {
      this.wxsOnPullingDown = onPullingDown;
      if (onPullingDown && !this.useChatRecordMode) {
        this.renderPropScrollTop = 0;
      }
    },
    //wxs正在下拉处理
    _handleWxsPullingDown({ moveDis, diffDis }) {
      this._emitTouchmove({ pullingDistance: moveDis, dy: diffDis });
    },
    //wxs触摸方向改变
    _handleTouchDirectionChange({ direction }) {
      this.$emit('touchDirectionChange', direction);
    },
    //wxs通知更新其props
    _handlePropUpdate() {
      this.wxsPropType = u.getTime().toString();
    },
    //下拉刷新结束
    _refresherEnd(shouldEndLoadingDelay = true, fromAddData = false, isUserPullDown = false, setLoading = true) {
      if (this.loadingType === Enum.LoadingType.Refresher) {
        let refresherCompleteDelay = 0;
        if (fromAddData && (isUserPullDown || this.showRefresherWhenReload)) {
          refresherCompleteDelay = this.refresherCompleteDuration > 700 ? 1 : this.refresherCompleteDelay;
        }
        const refresherStatus = refresherCompleteDelay > 0 ? Enum.Refresher.Complete : Enum.Refresher.Default;
        if (this.finalShowRefresherWhenReload) {
          const stackCount = this.refresherRevealStackCount;
          this.refresherRevealStackCount--;
          if (stackCount > 1) return;
        }
        this._cleanRefresherEndTimeout();
        this.refresherEndTimeout = setTimeout(
          () => {
            this.refresherStatus = refresherStatus;
          },
          this.refresherStatus !== Enum.Refresher.Default && refresherStatus === Enum.Refresher.Default ? this.refresherCompleteDuration : 0
        );

        // #ifndef APP-NVUE
        if (refresherCompleteDelay > 0) {
          this.isRefresherInComplete = true;
        }
        // #endif
        this._cleanRefresherCompleteTimeout();
        this.refresherCompleteTimeout = setTimeout(() => {
          let animateDuration = 1;
          const animateType = this.refresherEndBounceEnabled && fromAddData ? 'cubic-bezier(0.19,1.64,0.42,0.72)' : 'linear';
          if (fromAddData) {
            animateDuration = this.refresherEndBounceEnabled ? this.refresherCompleteDuration / 1000 : this.refresherCompleteDuration / 3000;
          }
          this.refresherTransition = `transform ${fromAddData ? animateDuration : this.refresherDefaultDuration / 1000}s ${animateType}`;
          // #ifndef APP-VUE || MP-WEIXIN || MP-QQ  || H5
          this.refresherTransform = 'translateY(0px)';
          this.currentDis = 0;
          // #endif
          // #ifdef APP-VUE || MP-WEIXIN || MP-QQ || H5
          this.wxsPropType = this.refresherTransition + 'end' + u.getTime();
          // #endif
          // #ifdef APP-NVUE
          this._nRefresherEnd();
          // #endif
          this.moveDis = 0;
          // #ifndef APP-NVUE
          if (refresherStatus === Enum.Refresher.Complete) {
            if (this.refresherCompleteSubTimeout) {
              clearTimeout(this.refresherCompleteSubTimeout);
              this.refresherCompleteSubTimeout = null;
            }
            this.refresherCompleteSubTimeout = setTimeout(() => {
              this.$nextTick(() => {
                this.refresherStatus = Enum.Refresher.Default;
                this.isRefresherInComplete = false;
              });
            }, animateDuration * 800);
          }
          // #endif
        }, refresherCompleteDelay);
      }
      if (setLoading) {
        setTimeout(
          () => {
            this.loading = false;
          },
          shouldEndLoadingDelay ? c.delayTime : 0
        );
        isUserPullDown && this._onRestore();
      }
    },
    //模拟用户手动触发下拉刷新
    _doRefresherRefreshAnimate() {
      this._cleanRefresherCompleteTimeout();
      // #ifndef APP-NVUE
      const doRefreshAnimateAfter = !this.doRefreshAnimateAfter && this.finalShowRefresherWhenReload && this.customRefresherHeight === -1 && this.refresherThreshold === '80rpx';
      if (doRefreshAnimateAfter) {
        this.doRefreshAnimateAfter = true;
        return;
      }
      // #endif
      this.refresherRevealStackCount++;
      // #ifndef APP-VUE || MP-WEIXIN || MP-QQ  || H5
      this.refresherTransform = `translateY(${this.finalRefresherThreshold}px)`;
      // #endif
      // #ifdef APP-VUE || MP-WEIXIN || MP-QQ || H5
      this.wxsPropType = 'begin' + u.getTime();
      // #endif
      this.moveDis = this.finalRefresherThreshold;
      this.refresherStatus = Enum.Refresher.Loading;
      this.isTouchmoving = true;
      this.isTouchmovingTimeout && clearTimeout(this.isTouchmovingTimeout);
      this._doRefresherLoad(false);
    },
    //触发下拉刷新
    _doRefresherLoad(isUserPullDown = true) {
      this._onRefresh(false, isUserPullDown);
      this.loading = true;
    },
    // #ifndef APP-VUE || MP-WEIXIN || MP-QQ || H5
    //获取处理后的moveDis
    _getFinalRefresherMoveDis(moveDis) {
      let diffDis = moveDis - this.oldCurrentMoveDis;
      this.oldCurrentMoveDis = moveDis;
      if (diffDis > 0) {
        diffDis = diffDis * this.finalRefresherPullRate;
        if (this.currentDis > this.finalRefresherThreshold) {
          diffDis = diffDis * (1 - this.finalRefresherOutRate);
        }
      }
      diffDis = diffDis > 100 ? diffDis / 100 : diffDis;
      this.currentDis += diffDis;
      this.currentDis = Math.max(0, this.currentDis);
      return this.currentDis;
    },
    //判断touch手势是否要触发
    _touchDisabled() {
      const checkOldScrollTop = this.oldScrollTop > 5;
      return (
        this.loading ||
        this.isRefresherInComplete ||
        this.useChatRecordMode ||
        !this.refresherEnabled ||
        !this.useCustomRefresher ||
        (this.usePageScroll && this.useCustomRefresher && this.pageScrollTop > 10) ||
        (!(this.usePageScroll && this.useCustomRefresher) && checkOldScrollTop)
      );
    },
    // #endif
    //更新自定义下拉刷新view高度
    _updateCustomRefresherHeight() {
      this._getNodeClientRect('.zp-custom-refresher-slot-view').then((res) => {
        this.customRefresherHeight = res ? res[0].height : 0;
        this.showCustomRefresher = this.customRefresherHeight > 0;
        if (this.doRefreshAnimateAfter) {
          this.doRefreshAnimateAfter = false;
          this._doRefresherRefreshAnimate();
        }
      });
    },
    //发射pullingDown事件
    _emitTouchmove(e) {
      // #ifndef APP-NVUE
      e.viewHeight = this.finalRefresherThreshold;
      // #endif
      e.rate = e.pullingDistance / e.viewHeight;
      this.hasTouchmove && this.$emit('refresherTouchmove', e);
    },
    //清除refresherCompleteTimeout
    _cleanRefresherCompleteTimeout() {
      this.refresherCompleteTimeout = this._cleanTimeout(this.refresherCompleteTimeout);
      // #ifdef APP-NVUE
      this._nRefresherEnd(false);
      // #endif
    },
    //清除refresherEndTimeout
    _cleanRefresherEndTimeout() {
      this.refresherEndTimeout = this._cleanTimeout(this.refresherEndTimeout);
    },
  },
};
